package edu.rpi.tw.pml.browsing.client.util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import com.gwtext.client.util.JSON;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;

/*
 * Helper class to parse JSON string.
 */
public class JSONParser {

	/*
	 * Parse JSON texts to an array of concept.
	 */
	public static ArrayList<String> string2ConceptArray(String json) {
		ArrayList<String> list = new ArrayList<String>();

		JavaScriptObject jsobj = JSON.decode(json);
		JSONObject jsono = new JSONObject(jsobj);
		JSONObject results = (JSONObject) jsono.get("results");
		JSONArray bindings = (JSONArray) results.get("bindings");
		for (int i = 0; i < bindings.size(); i++) {
			JSONObject binding = (JSONObject) bindings.get(i);
			JSONObject cls = (JSONObject) binding.get("concept");
			JSONString value = (JSONString) cls.get("value");
			list.add(value.stringValue());
		}

		return list;
	}

	/*
	 * Parse JSON texts to a hash table <String, Object[][]> String: instance
	 * id. Object[][]: property-value pair for each instance.
	 */
	public static LinkedHashMap<String, Object[][]> string2HashMap(String json) {
		LinkedHashMap<String, Object[][]> ht = new LinkedHashMap<String, Object[][]>();
		LinkedHashMap<String, LinkedList<Object[]>> hl = new LinkedHashMap<String, LinkedList<Object[]>>();
		ArrayList<String> dic = new ArrayList<String>();

		JavaScriptObject jsobj = JSON.decode(json);
		JSONObject jsonobj = new JSONObject(jsobj);
		JSONObject results = (JSONObject) jsonobj.get("results");
		JSONArray bindings = (JSONArray) results.get("bindings");
		for (int i = 0; i < bindings.size(); i++) {
			JSONObject binding = (JSONObject) bindings.get(i);
			JSONObject io = (JSONObject) binding.get("i");
			String iv = ((JSONString) io.get("value")).stringValue();

			JSONObject po = (JSONObject) binding.get("p");
			String pv = ((JSONString) po.get("value")).stringValue();

			JSONObject oo = (JSONObject) binding.get("o");
			String ov = ((JSONString) oo.get("value")).stringValue();

			if (!dic.contains(iv)) {
				dic.add(iv);
			}

			Object[] newPair = new Object[] { pv, ov };

			// Use URI of instance as key in hashmap
			if (!hl.containsKey(iv)) {
				LinkedList<Object[]> objl = new LinkedList<Object[]>();
				objl.add(newPair);
				hl.put(iv, objl);
			} else {
				LinkedList<Object[]> objl = hl.get(iv);
				objl.add(newPair);
				hl.put(iv, objl);
			}
		}

		for (int i = 0; i < dic.size(); i++) {
			String key = dic.get(i);
			LinkedList<Object[]> lo = hl.get(key);
			// convert LinkedList<Object[]> to Object[][]
			int size = lo.size();
			Object[][] value = new Object[size][];
			for (int j = 0; j < size; j++) {
				value[j] = lo.get(j);
			}
			ht.put(key, value);
		}

		return ht;
	}

	public static String[] string2FacetArray(String json) {
		ArrayList<String> list = new ArrayList<String>();

		JavaScriptObject jsobj = JSON.decode(json);
		JSONObject jsono = new JSONObject(jsobj);
		JSONObject results = (JSONObject) jsono.get("results");
		JSONArray bindings = (JSONArray) results.get("bindings");
		for (int i = 0; i < bindings.size(); i++) {
			JSONObject binding = (JSONObject) bindings.get(i);
			JSONObject cls = (JSONObject) binding.get("p");
			JSONString value = (JSONString) cls.get("value");
			list.add(value.stringValue());
		}

		return list.toArray(new String[] {});
	}

	public static String[] string2FacetValueArray(String json) {
		ArrayList<String> list = new ArrayList<String>();

		JavaScriptObject jsobj = JSON.decode(json);
		JSONObject jsono = new JSONObject(jsobj);
		JSONObject results = (JSONObject) jsono.get("results");
		JSONArray bindings = (JSONArray) results.get("bindings");
		for (int i = 0; i < bindings.size(); i++) {
			JSONObject binding = (JSONObject) bindings.get(i);
			JSONObject cls = (JSONObject) binding.get("o");
			JSONString value = (JSONString) cls.get("value");
			list.add(value.stringValue());
		}

		return list.toArray(new String[] {});

	}
}